<!DOCTYPE html>
<html>
	<head>
		<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
		
		<style>
			#search-container {
				margin-left: 200px;
				margin-top: 200px;
				width: 200px;
			}
			
			#search-term {
				width: 194px;
			}
			
			#search-dropdown {
				position: absolute;
				width: 200px;
				border-width: 0px 1px 1px 1px;
				border-style: solid;
				border-color: #cccccc;
				font-family: verdana;
			}
			
			.search-dropdown-item {
				margin: 2px;
				cursor: pointer;
				color: #000000;
				font-size: 12px;
			}
			
			.search-dropdown-item:hover {
				background-color: #cccccc;
			}
			
			.search-dropdown-item-selected {
				color: #ffffff !important;
				background-color: #97aaca !important;
			}
			
			#search-dropdown-footer {
				border-top: 1px solid #cccccc;
			}
			
			#search-dropdown-footer-content {
				white-space: nowrap;
				float: right;
				margin-right: 5px;
			}
			
			#search-dropdown-footer-left-nav, #search-dropdown-footer-right-nav {
				font-family: verdana;
				font-size: 12px;
				cursor: pointer;
			}
			
			#search-dropdown-footer-info {
				padding: 0px 5px;
				font-size: 10px;
			}
			
			.floatRight {
				float: right;
			}
		</style>
	</head>
	
	<body>
		<div id="search-container"><input type="text" id="search-term" name="searchTerm" value=""/></div>
	</body>
	
	<script type="text/javascript">
		/**
		 * @author: Kapil Kashyap
		 */
		searchDropDownPlugin = (function($) {
			/* Global variables */
			var baseId = 'search-dropdown', // default value
				baseCls = 'search-dropdown', // default value
				itemsPerPage = 5, // default value
				
				url = '',
				searchInputSelector = null,
				pageItems = [],
				currentPage = 1,
				maximumNumberOfPages = 1,
				totalSearchResults = null,
				startIndex = null,
				endIndex = null,
				paginationFooter = '',
				searchTerm = '';
				
				_success = function( data ) {
					alert( 'You need to provide the success callback in the config.' );
				};
				
			return {
				getFoo: function() {
					return this.foo;
				},
				reposition: function( componentSelector, relativeToSelector ) {
					var $component = $( componentSelector ),
						$relativeTo = typeof relativeToSelector == 'object' ? relativeToSelector : $( relativeToSelector ),
						
						_relativeToPosition = $relativeTo.position(),
						_relativeToHeight = $relativeTo.height();
					
					$component.css('left', _relativeToPosition.left);
					//$component.css('top', _relativeToPosition.top + _relativeToHeight - 1);					
				},
				
				initialize: function( config ) {
					// set-up the Global variables
					config = config ? config : {};
					baseId = config && config.baseId ? config.baseId : baseId;
					baseCls = config && config.baseCls ? config.baseCls : baseCls;
					searchInputSelector = config && config.searchInputSelector ? config.searchInputSelector : searchInputSelector;
					itemsPerPage = config && config.itemsPerPage ? config.itemsPerPage : itemsPerPage;
					url = config && config.url ? config.url : '';
					// callback
					_success = config && config.callbacks ? config.callbacks.success : _success;

					searchDropDownPlugin.constructPaginationFooter();
					searchDropDownPlugin.initializeEvents();
				},
				
				initializeEvents: function() {
					$( searchInputSelector ).keyup(function() {
						if( $.trim( this.value ).length > 0 ) {
							$.getJSON(url, $.trim( this.value ), _success);
						}
						else {
							var $search_dropdown = $( '#' + baseId );
							if( $( '#' + baseId ).length > 0 ) {
								$search_dropdown.remove();
							}
							// re-initialize the current page
							currentPage = 1;
						}
					});
					
					$( '.' + baseCls + '-item' ).live('click', function() {
						$( '#' + baseId ).find( '.' + baseCls + '-item-selected' ).removeClass( baseCls + '-item-selected' );
						$( this ).addClass( baseCls + '-item-selected' );
					});
					
					$( '#' + baseId + '-footer-right-nav' ).live('click', function() {
						if(currentPage < maximumNumberOfPages) {
							currentPage++;
							$( '#' + baseId ).html( searchDropDownPlugin.paginate( pageItems, itemsPerPage, currentPage ) );
							searchDropDownPlugin.updateFooterInfo();
						}
					});
					
					$( '#' + baseId + '-footer-left-nav' ).live('click', function() {
						if(currentPage > 1) {
							currentPage--;
							$( '#' + baseId ).html( searchDropDownPlugin.paginate( pageItems, itemsPerPage, currentPage ) );
							searchDropDownPlugin.updateFooterInfo();
						}
					});
				},
				
				constructDropDown: function( items ) {
					pageItems = items;
					// reset the currentPage property
					currentPage = 1;

					if( pageItems ) {
						if( $( '#' + baseId ).length > 0 ) {
							$( '#' + baseId ).html( '' );
							$( '#' + baseId ).html( searchDropDownPlugin.paginate( pageItems, itemsPerPage, currentPage ) );
							searchDropDownPlugin.updateFooterInfo();
							searchDropDownPlugin.reposition( '#' + baseId, searchInputSelector );
						}
						else {
							var $search_dropdown = $('<div/>', {
								'id': baseId,
								'width': $( searchInputSelector ).width(),
								html: searchDropDownPlugin.paginate( pageItems, itemsPerPage, currentPage )
							});
							
							$( 'body' ).append( $search_dropdown );
							searchDropDownPlugin.updateFooterInfo();
							searchDropDownPlugin.reposition( '#' + baseId, searchInputSelector );
						}
					}
				},
				
				constructPaginationFooter: function() {
					paginationFooter = '<div id="' + baseId + '-footer">';
						paginationFooter += '<div id="' + baseId + '-footer-content">';
							paginationFooter += '<span id="' + baseId + '-footer-left-nav">&lt;</span>';
							paginationFooter += '<span id="' + baseId + '-footer-info"></span>';
							paginationFooter += '<span id="' + baseId + '-footer-right-nav">&gt;</span>';
						paginationFooter += '</div>';
					paginationFooter += '</div>';
				},
				
				paginate: function(pageItems, itemsPerPage) {
					var threshold = itemsPerPage * currentPage,
						paginatedItems = [];
						
					maximumNumberOfPages = (pageItems.length % itemsPerPage > 0) 
											? Math.floor( pageItems.length / itemsPerPage ) + 1 
											: Math.floor( pageItems.length / itemsPerPage );
											
					totalSearchResults = pageItems.length;
					
					$.each(pageItems, function(index, item) {
						if(index == (threshold - itemsPerPage)) {
							startIndex = index;
						}
						if(index >= (threshold - itemsPerPage) && index < threshold) {
							paginatedItems.push(item);
							endIndex = index;
						}
					});
					
					if(maximumNumberOfPages > 1) {
						paginatedItems.push(paginationFooter);
					}
					
					return paginatedItems.join( '' );
				},
				
				updateFooterInfo: function() {
					$( '#' + baseId + '-footer-info' ).html( (startIndex + 1) + ' - ' + (endIndex + 1) + ' of ' + totalSearchResults);
				}
			}
		})(jQuery);
		
		jQuery( document ).ready(function() {
			var config = {
				baseId: 'search-dropdown',
				baseCls: 'search-dropdown',
				searchInputSelector: '#search-term', // Mandatory - the selector if search input element.
				url: 'response.json',
				itemsPerPage: 3,
				callbacks: {
					success: function( data ) {
						// your implementation of success callback
						var pageItems = [];
						// constructing minimal information that needs to be shown per item in the drop down container.
						$.each(data, function(index, item) {
							// CSS class 'search-dropdown-item' is derived from the baseCls + '-item' combo.
							pageItems.push('<div id="' + item.profilePrimaryEmail + '" class="search-dropdown-item">' + item.name + '</div>');
						});
						
						// pageItems is an array of items in the search drop down pages.
						// pageItems = ['item-1', 'item-2', 'item-3', ..., 'item-n']
						searchDropDownPlugin.constructDropDown( pageItems );
					}
				}
			};

			searchDropDownPlugin.initialize( config );
		});
	</script>
</html>
